import 'package:path/path.dart' as p;
import '../file_node.dart';

/// 自定义路径解析函数签名。
///
/// - [logicalPath]：逻辑路径（通常来自文件树 UI）；
/// - [node]：对应的 [FileNode] 节点；
/// - 返回：解析后的真实路径（未归一化）。
typedef RealPathResolver = String Function(String logicalPath, FileNode node);

/// [PathResolver]：负责将「逻辑路径 + 节点信息」解析为真实文件系统路径。
///
/// 功能：
/// - 提供统一的路径解析逻辑；
/// - 支持三层优先级：
///   1. **`FileNode.fullPath`**（节点自带的真实路径，优先级最高）；
///   2. **外部 resolver**（通过 [external] 注入，用于自定义映射规则，如虚拟文件系统）；
///   3. 解析失败 → 返回空字符串；
/// - 使用 [package:path] 进行路径归一化，避免不同平台下的路径分隔符差异。
///
/// 使用场景：
/// - `CreateService` / `DeleteService` / `FileExplorerManager` 在执行文件操作前，需要将 UI 层的逻辑路径转换为真实路径；
/// - 允许上层根据业务注入 [external]，例如多根目录映射、远程路径规则等。
///
/// 使用示例：
/// ```dart
/// final resolver = PathResolver(
///   external: (logicalPath, node) {
///     return '/workspace/$logicalPath/${node.name}';
///   },
/// );
///
/// final realPath = resolver.resolve('/src/utils', fileNode);
/// print(realPath); // 输出标准化后的真实路径
/// ```
class PathResolver {
  /// 可选的外部路径解析器，用于覆盖默认逻辑。
  final RealPathResolver? external;

  const PathResolver({this.external});

  /// 将逻辑路径与 [node] 解析为真实路径。
  ///
  /// 优先级：
  /// 1. 若 [FileNode.fullPath] 不为空 → 直接使用；
  /// 2. 若 [external] 不为空 → 调用外部 resolver；
  /// 3. 否则 → 返回空字符串。
  ///
  /// 返回值始终会经过 [_normalize] 处理。
  String resolve(String logicalPath, FileNode node) {
    // 1) fullPath 优先
    final fp = node.fullPath?.trim() ?? '';
    if (fp.isNotEmpty) return _normalize(fp);

    // 2) 外部 resolver
    if (external != null) {
      final r = external!(logicalPath, node).trim();
      if (r.isNotEmpty) return _normalize(r);
    }

    // 3) 失败
    return '';
  }

  /// 对路径进行归一化（统一分隔符等）。
  String _normalize(String input) => p.normalize(input);
}
